package cn.yunhe.springboot_shiro.config;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置
 * shiro核心通过filter来实现
 * 既然是用filter,所以要定义一系列关于url的规则和访问权限
 */
@Configuration
public class ShiroConfiguration {

    //身份认证realm
    @Bean(name = "myRealm")
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    /**
     * shiro 缓存管理器
     * 需要注入对应的其他实体类中:
     * 1,安全管理器:securityManager
     * securityManager是shiro的整个核心
     */
    @Bean(name = "securityManager")
    public SecurityManager securityManager(@Qualifier("myRealm") Realm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意：单独一个ShiroFilterFactoryBean配置是或报错的，以为在
     * 初始化ShiroFilterFactoryBean的时候需要注入：SecurityManager
     * <p>
     * Filter Chain定义说明
     * 1、一个URL可以配置多个Filter，使用逗号分隔
     * 2、当设置多个过滤器时，全部验证通过，才视为通过
     * 3、部分过滤器可指定参数，如perms，roles
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //shiro必须设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //配置退出过滤器,其中具体的退出代码shiro已经实现
        //anthc:所有url都必须认证通过才可以访问
        // anno:所有url都可以匿名访问
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/login.html","anon");
        filterChainDefinitionMap.put("/show.html","authc");
        filterChainDefinitionMap.put("/query", "authc");
        filterChainDefinitionMap.put("/update", "authc, roles[manager]");
        filterChainDefinitionMap.put("/update.html", "authc, roles[manager]");
        //过滤链定义,从上到下顺序执行,/**放在最下面
        filterChainDefinitionMap.put("/**", "authc");
        //如果不设置自动寻找web工程根目录下的/login.jsp页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized.html");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
}
